/*
      Aop编程暂时约用不上
 */


//package com.cxt.aop;
//
//import com.cxt.coordinateConversion.ConversionType;
//import com.cxt.coordinateConversion.CoordinateAutoConversion;
//import com.cxt.model.Coordinate;
//import com.cxt.utils.CoordinateUtil;
//import com.cxt.utils.GPSUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.Signature;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.stereotype.Component;
//
//import java.lang.reflect.Field;
//import java.math.BigDecimal;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
////坐标自动转换切面
//@Aspect
//@Component
//@Slf4j
//public class CoordinateAutoConversionAop {
//    static private Integer BD_TO_GCJ02 = 1;
//    static private Integer GCJ02_TO_BD = 2;
//
//    @Pointcut("execution(* com.cxt.controller.employee.*.*(*))")
//    public void autoFillPointCut() {
//    }
//
//    @Around("autoFillPointCut()")
//    public Object autoConversion(ProceedingJoinPoint joinPoint) throws Throwable {
//        //获取方法签名
//        Signature signature = joinPoint.getSignature();
//        //获取方法参数
//        Object[] args = joinPoint.getArgs();
//        for (Object arg : args) {
//            if (isNeedConversion(arg)) {
//                conversion(arg, GCJ02_TO_BD);
//            }
//        }
//        Object proceed = joinPoint.proceed();
//        if (isNeedConversion(proceed)) {
//            conversion(proceed, BD_TO_GCJ02);
//        }
//        return proceed;
//    }
//
//    /*判断对象是否否需要进行处理
//     * 常用于快速判断一个对象中是否需要进行坐标转换
//     * 直接把一个对象传入conversion也可以但是比较耗时
//     * 快速判读一个对象是否需要传入conversionObject
//     */
//    public boolean isNeedConversion(Object arg) throws IllegalAccessException {
//        //是不是空
//        //是就不处理
//        //是不是集合
//        //是集合就遍历集合，进行递归
//        //是不是在com.rds下
//        //是不是带有OBJ注解
//        //是就处理
//        //不是就遍历字段，进行递归
//        if (arg == null) {
//            //参数为空，不处理
//            return false;
//        }
//        //获取参数类型
//        Class<?> argType = arg.getClass();
//        //判断是否是集合类型
//        if (arg instanceof List) {
//            List list = (List) arg;
//            //判断集合中的对象是否有注解
//            for (Object o : list) {
//                return isNeedConversion(o);
//            }
//            return false;
//        }
//        //判断是不是在com.rds下
//        boolean isCom = arg.getClass().getName().startsWith("com.rds");
//        if (!isCom) {
//            //不在com.rds下，不处理
//            return false;
//        }
//        //判断类上是否有注解
//        boolean annotationPresent = argType.isAnnotationPresent(CoordinateAutoConversion.class);
//        if (annotationPresent) {//有注解，需要处理
//            return true;
//        }
//        //没有注解的对象，判断属性的对象是否有注解
//        Field[] fields = argType.getDeclaredFields();
//        for (Field field : fields) {
//            field.setAccessible(true);
//            String name = field.getType().getName();
//            //获取Object的全类名
//            Object o = field.get(arg);
//            boolean needConversion = isNeedConversion(o);//递归
//            if (needConversion) {//属性需要处理
//                return true;
//            }
//        }
//        return false;
//    }
//
//    /*
//     *遍历一个对象，对带有CoordinateAutoConversion注解且type为OBJECT的字段进行坐标转换
//     */
//    public void conversion(Object arg, Integer toType) throws IllegalAccessException {
//        //不管是不是带有注解，都进行遍历，如果是带有注解的就交给方法进行处理
//        //遍历时，对于对象，只对在com.rds下的包进行遍历
//        //是不是空
//        //是不是集合
//        //是--》判断一个集合元素是否有注解---》有注解--》处理--》没有注解--》结束
//        //是不是在com.rds下
//        //是不是带有OBJ注解
//        //是--》处理
//        //是||不是-》遍历字段，递归
//
//        //是不是空
//        if (arg == null) {
//            //参数为空，不处理
//            return;
//        }
//        //获取参数类型
//        Class<?> argType = arg.getClass();
//        //判断是否是集合类型
//        if (arg instanceof List) {
//            //处理集合
//            List list = (List) arg;
//            boolean annotationPresent = false;
//            //判断集合中的对象是否有注解
//            for (Object o : list) {
//                annotationPresent = isNeedConversion(o);
//                break;
//            }
//            if (annotationPresent) {//集合中的对象需要处理
//                for (Object o : list) {
//                    conversion(o, toType);
//                }
//            }
//            return;
//        }
//        //是不是在com.rds下
//        boolean isCom = arg.getClass().getName().startsWith("com.rds");
//        if (!isCom) {
//            //不在com.rds下，不处理
//            return;
//        }
//        //判断类上是否有注解
//        boolean annotationPresent = argType.isAnnotationPresent(CoordinateAutoConversion.class);
//        if (annotationPresent) {//有注解，需要处理
//            conversionObject(arg, toType);
//        }
//        //没有注解的对象，遍历字段进行递归
//        Field[] fields = argType.getDeclaredFields();
//        for (Field field : fields) {
//            field.setAccessible(true);
//            Object o = field.get(arg);
//            conversion(o, toType);//递归
//        }
//    }
//
//    /*
//     *处理需要进行坐标转换的对象
//     */
//    private void conversionObject(Object arg, Integer toType) throws IllegalAccessException {
//        //如果是空，不处理
//        if (arg == null) {
//            return;
//        }
//        Class<?> argType = arg.getClass();
//        //获取所有字段
//        Field[] fields = argType.getDeclaredFields();
//        //存储一对坐标
//        Map<ConversionType, Field> coordinateMap = new HashMap<>();
//        //遍历所有字段
//        for (Field field : fields) {
//            //属性带注解
//            boolean apField = field.isAnnotationPresent(CoordinateAutoConversion.class);
//            //属性上带注解进行处理
//            if (apField) {
//                //处理
//                CoordinateAutoConversion annotation1 = field.getAnnotation(CoordinateAutoConversion.class);
//                ConversionType type1 = annotation1.type();
//                if (type1 == ConversionType.BigDecimalLat || type1 == ConversionType.BigDecimalLng) {//BigDecimal类型的经纬度
//                    coordinateMap.put(type1, field);
//                    if (coordinateMap.get(ConversionType.BigDecimalLat) != null
//                            && coordinateMap.get(ConversionType.BigDecimalLng) != null) {
//                        //处理逻辑
//                        conversionByBigDecimalLatLngMap(arg, coordinateMap, toType);
//                        //清空Map
//                        coordinateMap.clear();
//                    }
//                    continue;
//                }
//                conversionByConversionType(arg, field, type1, toType);
//            }
//        }
//
//
//    }
//
//    /*
//     *处理带有注解的字段
//     * 专门处理单字段的经纬度
//     */
//    void conversionByConversionType(Object arg, Field field, ConversionType type, Integer toType) throws IllegalAccessException {
//        if (type == ConversionType.StringLngLat) {//对StringLngLat类型进行处理
//            //处理逻辑
//            //字段值允许修改
//            field.setAccessible(true);
//            //获取参数的值
//            Object value = field.get(arg);
//            //转成String对象
//            String latLng = (String) value;
//            //生成坐标对象
//            Coordinate coordinate = CoordinateUtil.StringToCoordinate(latLng);
//            //进行坐标转换
//            Coordinate newCoordinate = conversionCoordinate(coordinate, toType);
//            //转回字符串
//            String newLatLng = CoordinateUtil.CoordinateToString(newCoordinate);
//            //修改参数的值
//            field.set(arg, newLatLng);
//        }
//        //废弃
////        else if(type==ConversionType.COORDINATE){//对象
////            Class<?> aClass = field.getClass();
////            //获取参数的值
////            Object value = field.get(arg);
////            //转成Coordinate对象
////            Coordinate coordinate = (Coordinate)value;
////            //进行坐标转换
////            Coordinate newCoordinate = conversionCoordinate(coordinate, toType);
////            //修改参数的值
////            field.set(arg,newCoordinate);
////        }
//    }
//
//    /*
//     *处理带有注解的字段
//     * 专门处理BigDecimal类型的经纬度
//     * BigDecimal类型的经纬度需要两个字段
//     */
//    void conversionByBigDecimalLatLngMap(Object arg, Map<ConversionType, Field> coordinateMap, Integer toType) throws IllegalAccessException {
//        //处理逻辑
//        //修改参数的值
//        Field fieldLat = coordinateMap.get(ConversionType.BigDecimalLat);
//        Field fieldLng = coordinateMap.get(ConversionType.BigDecimalLng);
//        //字段值允许修改
//        fieldLat.setAccessible(true);
//        fieldLng.setAccessible(true);
//        //获取参数的值
//        Object valueLat = fieldLat.get(arg);
//        Object valueLng = fieldLng.get(arg);
//        //进行类型转换
//        BigDecimal lat = (BigDecimal) valueLat;
//        BigDecimal lng = (BigDecimal) valueLng;
//        //生成Coordinate对象
//        Coordinate coordinate = new Coordinate(lng, lat);
//        //进行坐标转换
//        Coordinate newCoordinate = conversionCoordinate(coordinate, toType);
//        //修改参数的值
//        BigDecimal newLat = newCoordinate.getLat();
//        BigDecimal newLng = newCoordinate.getLng();
//        //修改参数的值
//        fieldLat.set(arg, newLat);
//        fieldLng.set(arg, newLng);
//    }
//
//    /*
//     *坐标转换
//     * 根据toType进行坐标转换
//     * toType=1 BD_TO_GCJ02
//     * toType=2 GCJ02_TO_BD
//     */
//    Coordinate conversionCoordinate(Coordinate coordinate, Integer toType) {
//        if (toType.equals(BD_TO_GCJ02)) {
//            double[] doubles = GPSUtil.bd09_To_Gcj02(coordinate.getLat().doubleValue(), coordinate.getLng().doubleValue());
//            coordinate.setLat(new BigDecimal(doubles[0]));
//            coordinate.setLng(new BigDecimal(doubles[1]));
//        } else if (toType.equals(GCJ02_TO_BD)) {
//            double[] doubles = GPSUtil.gcj02_To_Bd09(coordinate.getLat().doubleValue(), coordinate.getLng().doubleValue());
//            coordinate.setLat(new BigDecimal(doubles[0]));
//            coordinate.setLng(new BigDecimal(doubles[1]));
//        }
//        return coordinate;
//    }
//}
